Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore unknown elements #121

Closed

Conversation

fjolnir
Copy link
Member

@fjolnir fjolnir commented Mar 29, 2018

See: #118

Copy link
Member Author

@fjolnir fjolnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the help! I hope my comments aren't too pedantic 🙇‍♂️

SVGEngine.mm Outdated
while(xmlTextReaderRead(_xmlReader) == 1) {
int const type = xmlTextReaderNodeType(_xmlReader);
const char * const tag = (char *)xmlTextReaderConstName(_xmlReader);

CGPathRef path = NULL;
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "path") == 0)
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "svg") == 0) {
Copy link
Member Author

@fjolnir fjolnir Mar 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's insert a comment here along the lines of

if (tag==<svg>) {
    // Prevent <svg> from being ignored`
} else ...```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

SVGEngine.mm Outdated
@@ -125,7 +133,9 @@ @interface SVGAttributeSet () {
pushGroup(readAttributes());
else if(type == XML_READER_TYPE_END_ELEMENT)
popGroup();
}
} else if(type == XML_READER_TYPE_ELEMENT)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use curlies {}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally this check should just be if (type == XML_READER_TYPE_ELEMENT && !xmlTextReaderIsEmptyElement(_xmlReader)) skipping the next if statement

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is changing to be a single-line branch I presume that you don't want curlies around it, in order to match the rest of the code here?

SVGEngine.mm Outdated
@@ -103,12 +103,20 @@ @interface SVGAttributeSet () {
valueOptions:NSMapTableStrongMemory];
NSMutableArray * const paths = [NSMutableArray new];

unsigned int depthWithinUnknownElement = 0;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file uses NSUInteger.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

SVGEngine.mm Outdated
while(xmlTextReaderRead(_xmlReader) == 1) {
int const type = xmlTextReaderNodeType(_xmlReader);
const char * const tag = (char *)xmlTextReaderConstName(_xmlReader);

CGPathRef path = NULL;
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "path") == 0)
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "svg") == 0) {
} else if(depthWithinUnknownElement > 0) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be a bit more readable if this check came first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More correct too, 💯

@fjolnir
Copy link
Member Author

fjolnir commented Mar 29, 2018

I'm not sure if there are any wrapper tags that we wouldn't want to ignore. Best to be careful here.

Copy link
Contributor

@cysp cysp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, just saw that this PR got raised.
I'll go through and make the changes soon.

SVGEngine.mm Outdated
while(xmlTextReaderRead(_xmlReader) == 1) {
int const type = xmlTextReaderNodeType(_xmlReader);
const char * const tag = (char *)xmlTextReaderConstName(_xmlReader);

CGPathRef path = NULL;
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "path") == 0)
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "svg") == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

SVGEngine.mm Outdated
while(xmlTextReaderRead(_xmlReader) == 1) {
int const type = xmlTextReaderNodeType(_xmlReader);
const char * const tag = (char *)xmlTextReaderConstName(_xmlReader);

CGPathRef path = NULL;
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "path") == 0)
if(type == XML_READER_TYPE_ELEMENT && strcasecmp(tag, "svg") == 0) {
} else if(depthWithinUnknownElement > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More correct too, 💯

SVGEngine.mm Outdated
@@ -103,12 +103,20 @@ @interface SVGAttributeSet () {
valueOptions:NSMapTableStrongMemory];
NSMutableArray * const paths = [NSMutableArray new];

unsigned int depthWithinUnknownElement = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@cysp cysp force-pushed the feature/ignore-unknown-elements branch from 02e2c31 to cf9525a Compare April 4, 2018 04:07
@cysp
Copy link
Contributor

cysp commented Apr 4, 2018

Comments addressed (I think) in a fixup! commit on top, to be squashed prior to merge.
I'm not sure what direction to take from the suggestion to be careful when ignoring elements though?

Of the "container" and "structural" elements, I think the only one that could be correctly handled by rendering its contents into the document would be a, but it can still have styling and transformation attributes on it, so I think that they would have to be handled similarly to g, by pushing and popping the context?

@fjolnir
Copy link
Member Author

fjolnir commented Apr 4, 2018

Changes look good. Could you add || strcasecmp(tag, "a") == 0 to the group check?

@cysp cysp force-pushed the feature/ignore-unknown-elements branch from cf9525a to 264ed73 Compare April 4, 2018 07:46
@arielelkin
Copy link
Collaborator

Just a quick headsup: we now have a CHANGELOG to make it easier to keep track of new features and bugs, and to credit our contributors. It'd be great if your PR also updates it.

@cysp
Copy link
Contributor

cysp commented Apr 5, 2018

A test suite too! I'll make up some cases for this change.

@cysp cysp force-pushed the feature/ignore-unknown-elements branch from 264ed73 to d1976bb Compare April 5, 2018 02:09
@cysp
Copy link
Contributor

cysp commented Apr 5, 2018

The tests are pretty cheesy but they do test the functionality. :-)
I tried to use a transform in the "respects attributes on <a> elements" test but it seems that the svg string representation code doesn't deal with that (it blows up on non-string, non-CGColorRef attribute values) and fixing that turned into too much change to throw into this PR.

@cysp
Copy link
Contributor

cysp commented Apr 5, 2018

Also it looks like the ordering of attributes in the produced SVG string is not fixed? The ordering does seem deterministic, as the tests pass once the magic ordering for that testcase is determined, but it's not predictable?

@fjolnir
Copy link
Member Author

fjolnir commented Apr 5, 2018

The order is undefined.

@cysp
Copy link
Contributor

cysp commented Apr 5, 2018

Hm, indeed.
Looks like the existing tests (and now these) were just getting lucky when iterating over the NSDictionary.
Fortunately these tests can fairly easily be changed to just inspect the attributes set on each path rather than implicitly doing that by testing the string representation.

@fjolnir
Copy link
Member Author

fjolnir commented Apr 5, 2018

You could x=parse(svg) and check that parse(generateSvg(x)) == x

@cysp cysp force-pushed the feature/ignore-unknown-elements branch from d1976bb to 9ca0d9c Compare April 5, 2018 02:39
@cysp cysp force-pushed the feature/ignore-unknown-elements branch from 9ca0d9c to 87e6b71 Compare April 5, 2018 02:55
let paths = SVGBezierPath.paths(fromSVGString: svgString)
XCTAssertEqual(paths.count, 1)

guard let path = paths.first else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if XCTAssertEqual(paths.count, 1) passes, then we know that paths.first != nil, so this guard let is redundant and it's safe to do path!.bounds below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured that bailing after failing the assertion was friendlier than hitting a fatal error and breaking the whole test run in the case that we don't parse any paths out of the svg?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an individual test's execution stops as soon as an assertion fails, so if we don't parse any paths out of the svg we'll duly fail the assertion on line 101 and we're guaranteed not to execute the code with the force unwrap.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. That’s not how Xcode (9.3) behaves on my computer and I can’t see .continueAfterFailure being set anywhere. Is that a global configuration option in Xcode?

Copy link
Collaborator

@arielelkin arielelkin Apr 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, sorry, you're absolutely right, I hadn't set .continueAfterFailure to false

I have now: 1c014fa

let paths = SVGBezierPath.paths(fromSVGString: svgString)
XCTAssertEqual(paths.count, 1)

guard let path = paths.first else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto as above.

@arielelkin
Copy link
Collaborator

@fjolnir

You could x=parse(svg) and check that parse(generateSvg(x)) == x

If ordering of attributes is undefined, this could fail even if parsing and generation are done properly, no?

@arielelkin
Copy link
Collaborator

Fortunately these tests can fairly easily be changed to just inspect the attributes set on each path rather than implicitly doing that by testing the string representation.

Testing that the SVGAttributes are correctly set is another test (which I've now added). But what I wanted to test was that the string representation is correctly generated.

I thought of doing something like:

XCTAssert(bezierPath.svgRepresentation.contains("<path stroke=\"black\""))

but if attributes can be in order, then this test will unduly fail if we generated <path fill=\"transparent\" stroke=\"black\"

So we could simplify the tests to this extent:

XCTAssert(bezierPath.svgRepresentation.contains("stroke=\"black\""))

Do you find that'd be at all useful ?

@cysp
Copy link
Contributor

cysp commented Apr 5, 2018

Oh, I meant specifically these tests for this functionality being easily changed to just test the attributes. I think the existing string representation tests certainly do have a place and IMO they're most useful remaining as holistic document tests, as long as the contents of the documents can be given a stable ordering.

@arielelkin
Copy link
Collaborator

@cysp @fjolnir

Please let me know if there are any other changes you'd like to make to this PR, as I'd like to merge it within a couple of days. I can take care of removing the guard let (see #121 (review)).

@arielelkin
Copy link
Collaborator

merged via fc4c0af

@arielelkin arielelkin closed this Jun 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants